package com.lagou.edu.filer;

import com.lagou.edu.model.Stat;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;

import java.util.Date;
import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @program: stage-3-module-3
 * @description:
 * @author: zhangxiaoyang
 * @date: 2020-09-02 14:03
 **/
@Activate(group = {CommonConstants.CONSUMER})
public class TPMonitorFilter implements Filter {

    private static final Map<String, AtomicInteger> methodCount = new ConcurrentHashMap<>();
    public static final Map<String, LinkedList<Stat>> PERFORMANCE_MAP = new ConcurrentHashMap<>();
    private long initTime;

    static {
        methodCount.put("monitorA", new AtomicInteger(0));
        methodCount.put("monitorB", new AtomicInteger(0));
        methodCount.put("monitorC", new AtomicInteger(0));
    }

    {
        initTime = System.currentTimeMillis();
    }


    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        LinkedList<Stat> statQueue = PERFORMANCE_MAP.getOrDefault(invocation.getMethodName(), new LinkedList<>());
        Stat stat = new Stat();
        stat.setTimeStamp(System.currentTimeMillis());
        stat.setMethodCallCount(methodCount.get(invocation.getMethodName())
                                           .incrementAndGet());
        System.out.println(DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss") + "========" + invocation.getMethodName() + "==========请求次数:" + stat.getMethodCallCount());
        long startTime = System.currentTimeMillis();
        Result result = invoker.invoke(invocation);
        stat.setResponseTime(System.currentTimeMillis() - startTime);
        if (System.currentTimeMillis() - initTime > 1 * 60 * 1000) {
            statQueue.removeFirst();
        }
        statQueue.addLast(stat);
        PERFORMANCE_MAP.put(invocation.getMethodName(), statQueue);
        return result;
    }
}
